package com.sunfeng.two.p2;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import util.ConnectionUtil;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * @Author : 清风冷影
 * @Description:
 * @Date : 2021/8/20  13:54
 */
public class Worker03 {

    private static final String TASK_QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        final Channel channel = ConnectionUtil.getChannel();
        // 设置客户端最多接收未被 ack 的消息的个数   预取值
        /**  不公平分发
         *     ----意思就是如果这个任务我还没有处理完或者我还没有应答你，你先别分配给我，
         * 欲取值
         *     ---- 该值定义通道上允许的未确认消息的最大数量。
         * 消息应答和 QoS 预取值对用户吞吐量有重大影响。通常，增加预取将提高向消费者传递消息的速度。
         *  未确认的消息缓冲区 限制此消息的缓冲区大小，以避免缓冲区里面危险值的未确认消息问题
         *
         * 应该小心使用具有无限预处理的自动确认模式或手动确认模式，消费者消费了大量的消息如果没有确认的话，会导致消费者连接节点的
         * 内存消耗变大，所以找到合适的预取值是一个反复试验的过程，不同的负载该值取值也不同 100 到 300 范围内的值通常可提供最佳的吞吐量，并且不会给消费者带来太大的风险。
         */
       channel.basicQos(1);
        System.out.println("C2 等待接受消息处理时间比较长的");
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            try {
                TimeUnit.SECONDS.sleep(30);
                System.out.println(" 接受到消息: " + new String(message.getBody()));
                channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        };
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println(consumerTag + "取消接受逻辑");
        };

        //autoAck设置为false 可以防止消息不必要的丢失   建议设置为false
        channel.basicConsume(TASK_QUEUE_NAME, false, deliverCallback, cancelCallback);

    }
}
